<template>
  <div class="flow-main">
    <div :id="containerId"></div>
  </div>
</template>
<script lang="ts" setup>
import { APP_ENV_INFO } from "@/config";
import { getId } from "@/utils/id";
import { Graph, Snapline } from "@antv/x6";
const props = withDefaults(
  defineProps<{
    width?: number;
    height?: number;
    backgroundColor?: string;
    /** 是否盛满容器 */
    autoResize?: boolean;
    /** 初始化居中 */
    initCenter?: boolean;
    /** 显示对齐线 */
    showSnapline?: boolean;
    /** (展示)网格 */
    grid?: number;
    /** 画布平移 */
    panning?: boolean;
    /** 鼠标缩放 */
    mousewheel?: boolean;
  }>(),
  {
    width: 800,
    height: 600,
    backgroundColor: "#ff0",
    autoResize: true,
    initCenter: true,
    showSnapline: true,
    grid: 10,
    panning: true,
    mousewheel: true,
  },
);
/** 容器id */
const containerId = getId(`flow-main-container`);

const data = {
  nodes: [
    {
      id: "node1",
      shape: "rect",
      x: 40,
      y: 40,
      width: 100,
      height: 40,
      label: "hello",
      attrs: {
        // body 是选择器名称，选中的是 rect 元素
        body: {
          stroke: "#8f8f8f",
          strokeWidth: 1,
          fill: "#fff",
          rx: 6,
          ry: 6,
        },
      },
    },
    {
      id: "node2",
      shape: "rect",
      x: 160,
      y: 180,
      width: 100,
      height: 40,
      label: "world",
      attrs: {
        body: {
          stroke: "#8f8f8f",
          strokeWidth: 1,
          fill: "#fff",
          rx: 6,
          ry: 6,
        },
      },
    },
  ],
  edges: [
    {
      shape: "edge",
      source: "node1",
      target: "node2",
      label: "x6",
      attrs: {
        // line 是选择器名称，选中的边的 path 元素
        line: {
          stroke: "#8f8f8f",
          strokeWidth: 1,
        },
      },
    },
  ],
};

const graph = shallowRef<Graph>();

/** 初始化 */
const init = () => {
  const instance = new Graph({
    container: document.getElementById(containerId)!,
    autoResize: props.autoResize,
    // 设置画布大小
    width: props.width,
    height: props.height,
    // 设置画布背景颜色
    background: {
      color: props.backgroundColor,
    },
    grid: props.grid,
    panning: props.panning,
    mousewheel: props.mousewheel,
  });

  instance.fromJSON(data);

  /** 初始化居中 */
  if (props.initCenter) {
    instance.centerContent();
  }

  /** 展示对齐线 */
  if (props.showSnapline) {
    instance.use(
      new Snapline({
        enabled: true,
      }),
    );
  }

  graph.value = instance;

  return instance;
};

const getData = () => {
  return graph.value!.toJSON();
};

/** 非生产环境添加实例到x6调试工具 */
const addInstanceToX6DevTools = (instance?: Graph) => {
  if (!APP_ENV_INFO.isProd && instance) {
    window.__x6_instances__ = window.__x6_instances__ || [];
    window.__x6_instances__.push(instance);
  }
};

/** 非生产环境从x6调试工具中移除当前实例 */
const removeInstanceFromX6DevTools = (instance?: Graph) => {
  if (
    !APP_ENV_INFO.isProd &&
    instance &&
    Array.isArray(window.__x6_instances__)
  ) {
    window.__x6_instances__ = window.__x6_instances__.filter(
      (item) => item !== instance,
    );
  }
};

onMounted(() => {
  const instance = init();
  addInstanceToX6DevTools(instance);
});

onBeforeMount(() => {
  graph.value?.dispose();
  removeInstanceFromX6DevTools(graph.value);
});

defineExpose({
  getData,
});
</script>
